//
//  CredentialsProviderTests.m
//  cspsdk
//
//  Created by 罗宋汤 on 15/8/28.
//  Copyright (c) 2015年 CHANJET. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "CSPNetworking.h"
#import "CSPIdentityService.h"
#import "CSPTask.h"
#import "CSPTask+PromiseLike.h"
#import "CSPNetworkingRequest.h"
#import "OCMArg.h"
#import "OCMock.h"
#import "OCMMacroState.h"
#import "OCMStubRecorder.h"
#import "OCMockObject.h"
#import "OCMLocation.h"
#import "CSPCategory.h"
#import "CSPLogging.h"
#import <OCMock/OCMock.h>

@interface CredentialsProviderTests : XCTestCase

@end

@implementation CredentialsProviderTests

- (void)setUp {
    [super setUp];
    [CSPLogger defaultLogger].logLevel = CSPLogLevelVerbose;
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

//- (void)testApplySignupCodeWithMobile {
//    CSPIdentityService * service = [[CSPIdentityService alloc] init];
//    CSPIdentityApplySignupCodeRequest * request;
//
//    /**
//    * 测试手机号码格式正确，并且没有注册过。验证码成功发出
//    */
//    request = [CSPIdentityApplySignupCodeRequest modelWithDictionary:@{
//            @"accountType": @(CSPIdentityAccountMobile),
//            @"account": @"18910886729"
//    } error:nil];
//
//    [[[service applySignupCode:request] continueWithBlock:^id(CSPTask *task) {
//        XCTAssertNil(task.error);
//        XCTAssertNil(task.result);
//        return nil;
//    }] waitUntilFinished];
//}

/**
* 测试获取要申请注册手机的验证码
*/
- (void)testApplySignupCode {
    id mockNetworking = OCMClassMock([CSPNetworking class]);
    CSPIdentityService * service = [[CSPIdentityService alloc] init];
    CSPIdentityApplySignupCodeRequest * request;
    CSPIdentityApplySignupCodeResponse * mockStore;

    [service setValue:mockNetworking forKey:@"networking"];

    /**
    * 模拟测试手机号码格式正确，并且没有注册过。验证码成功发出
    */
    mockStore = [CSPIdentityApplySignupCodeResponse modelWithDictionary:@{
            @"exist": @NO
    } error:nil];
    request = [CSPIdentityApplySignupCodeRequest modelWithDictionary:@{
            @"accountType": @(CSPIdentityAccountMobile),
            @"account": @"you mobile"
    } error:nil];

    OCMStub([mockNetworking sendRequest:[OCMArg isKindOfClass:[CSPNetworkingRequest class]]])
            .andReturn([CSPTask taskWithResult:mockStore]);

    [[[service applySignupCode:nil] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNil(task.error);
        XCTAssertNil(task.result);
        return nil;
    }] waitUntilFinished];

    OCMVerify([mockNetworking sendRequest:[OCMArg isNotNil]]);

    /*
    * 模拟测试手机号码已经存在，errorCode 返回 CSPIdentitySignupAccountExists
     */
    mockNetworking = OCMClassMock([CSPNetworking class]);
    [service setValue:mockNetworking forKey:@"networking"];

    mockStore = [CSPIdentityApplySignupCodeResponse modelWithDictionary:@{
            @"exist": @YES
    } error:nil];

    OCMStub([mockNetworking sendRequest:[OCMArg isKindOfClass:[CSPNetworkingRequest class]]])
            .andReturn([CSPTask taskWithResult:mockStore]);

    [[[service applySignupCode:nil] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNotNil(task.error);
        XCTAssertEqual(task.error.domain, CSPIdentityErrorDomain);
        XCTAssertEqual(task.error.code, CSPIdentitySignupAccountExists);
        return nil;
    }] waitUntilFinished];

    OCMVerify([mockNetworking sendRequest:[OCMArg isNotNil]]);

    /*
    * 模拟测试手机号码格式不正确的情况。
     */
    mockNetworking = OCMClassMock([CSPNetworking class]);
    [service setValue:mockNetworking forKey:@"networking"];

    mockStore = [CSPIdentityApplySignupCodeResponse modelWithDictionary:@{
            @"exist": @NO,
            @"errorCode" : @(10002)
    } error:nil];

    OCMStub([mockNetworking sendRequest:[OCMArg isKindOfClass:[CSPNetworkingRequest class]]])
            .andReturn([CSPTask taskWithResult:mockStore]);

    [[[service applySignupCode:nil] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNotNil(task.error);
        XCTAssertEqual(task.error.domain, CSPIdentityErrorDomain);
        XCTAssertEqual(task.error.code, CSPIdentityErrorInvalidParameter);
        return nil;
    }] waitUntilFinished];

    OCMVerify([mockNetworking sendRequest:[OCMArg isNotNil]]);
}

- (void)testLoginWithAccountPassword {
    id mockNetworking = OCMClassMock([CSPNetworking class]);

    CSPIdentityGetCredentialsResponse * mockStore = [CSPIdentityGetCredentialsResponse modelWithDictionary:@{
        @"accessToken": @"1",
            @"refreshToken": @"2",
            @"account": @"foo@chanjet.com",
            @"userId": @"6501"
    } error:nil];
    OCMStub([mockNetworking sendRequest:[OCMArg isKindOfClass:[CSPNetworkingRequest class]]])
            .andReturn([CSPTask taskWithResult:mockStore]);

    CSPIdentityService * service = [[CSPIdentityService alloc] init];
    [service setValue:mockNetworking forKey:@"networking"];

    CSPIdentityLoginWithAccountRequest * request = [CSPIdentityLoginWithAccountRequest modelWithDictionary:@{
            @"account": @"foo@chanjet.com",
            @"password": @"223830",
            @"needInviteList": @"0",
            @"coop": @"iOS",
            @"endpoint_id": [NSString stringWithFormat:@"%f", [NSDate date].timeIntervalSince1970]
    } error:nil];

    [[[service loginWithAccountPassword:request] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNil(task.error);
        XCTAssertNil(task.exception);
        //确认已经成功保存了Identity
        XCTAssertTrue([task.result isKindOfClass:[CSPIdentityStore class]]);
        XCTAssertEqual([task.result valueForKey:@"accessKey"], mockStore.accessToken);

        return nil;
    }] waitUntilFinished];

    OCMVerify([mockNetworking sendRequest:[OCMArg isNotNil]]);
}

- (void)testLoginWithAccountPasswordSuccess {
    CSPIdentityService * service = [[CSPIdentityService alloc] init];
    CSPIdentityLoginWithAccountRequest * request = [CSPIdentityLoginWithAccountRequest modelWithDictionary:@{
            @"account": @"syq@chanjet.com",
            @"password": @"223830",
            @"needInviteList": @"0",
            @"coop": @"iOS",
            @"endpoint_id": [NSString stringWithFormat:@"%f", [NSDate date].timeIntervalSince1970]
    } error:nil];

    [[[service loginWithAccountPassword:request] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNil(task.error);
        XCTAssertNil(task.exception);
        XCTAssertNotNil(task.result);
        return nil;
    }] waitUntilFinished];
}

- (void)testLoginWithAccountPasswordFailed {
    id ex1 = [self expectationWithDescription:@""];

    CSPIdentityService * service = [[CSPIdentityService alloc] init];
    CSPIdentityLoginWithAccountRequest * request = [CSPIdentityLoginWithAccountRequest modelWithDictionary:@{
            @"account": @"syq@chanjet.com",
            @"password": @"123456",
            @"needInviteList": @"0",
            @"coop": @"iOS",
            @"endpoint_id": [NSString stringWithFormat:@"%f", [NSDate date].timeIntervalSince1970]
    } error:nil];

    [[service loginWithAccountPassword:request] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNotNil(task.error);
        XCTAssertNil(task.exception);
        XCTAssertNil(task.result);

        [ex1 fulfill];

        return nil;
    }];

    [self waitForExpectationsWithTimeout:10 handler:nil];
}

/**
*   测试刷新Token
*/
- (void)testRefreshToken {
    id ex1 = [self expectationWithDescription:@""];

    CSPIdentityService * service = [[CSPIdentityService alloc] init];
    CSPIdentityLoginWithAccountRequest * request = [CSPIdentityLoginWithAccountRequest modelWithDictionary:@{
            @"account": @"syq@chanjet.com",
            @"password": @"223830",
            @"needInviteList": @"0",
            @"coop": @"iOS",
            @"endpoint_id": [NSString stringWithFormat:@"%f", [NSDate date].timeIntervalSince1970]
    } error:nil];

    [[[service loginWithAccountPassword:request] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNil(task.error);
        XCTAssertNil(task.exception);
        XCTAssertNotNil(task.result);

        return [service refreshToken];
    }] continueWithBlock:^id(CSPTask *task) {
        XCTAssertNil(task.error);
        XCTAssertNil(task.exception);
        XCTAssertNotNil(task.result);

        [ex1 fulfill];
        return nil;
    }];

    [self waitForExpectationsWithTimeout:10 handler:nil];
}

/**
*   测试退出账号
*/
- (void)testUserLogout {
    CSPIdentityService * service = [[CSPIdentityService alloc] init];
    CSPIdentityLoginWithAccountRequest * request = [[CSPIdentityLoginWithAccountRequest alloc] init];
    request.account = @"17001098622";
    request.password = @"223830";
    request.needInviteList = @"0";
    request.coop = @"iOS";
    request.endpoint_id =[NSString stringWithFormat:@"%f", [NSDate date].timeIntervalSince1970];

    [[service loginWithAccountPassword:request].then(^id(CSPIdentityStore *store) {
        XCTAssertNotNil(store);
        return [service logout];
    }).then(^id(id result) {
        XCTAssertNil(result);
        return nil;
    }) waitUntilFinished];

//    [[[[service loginWithAccountPassword:request] continueWithBlock:^id(CSPTask *task) {
//        XCTAssertNil(task.error);
//        XCTAssertNil(task.exception);
//        XCTAssertNotNil(task.result);
//
//        return [service logout];
//    }] continueWithBlock:^id(CSPTask *task) {
//        XCTAssertNil(task.error);
//        XCTAssertNil(task.exception);
//        XCTAssertNil(task.result);
//
//        return nil;
//    }] waitUntilFinished];
}

@end
